home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 1.iso / icons / animator.zip / CHILD.C < prev    next >
C/C++ Source or Header  |  1993-02-18  |  18KB  |  691 lines

  1. #include "animator.h"
  2.  
  3.  
  4. static char szAllPurpose [MAX_FILE_SIZE];
  5.  
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9.  
  10. BOOL NEAR PASCAL Child_OnCreate (HWND, LPCREATESTRUCT);
  11. VOID NEAR PASCAL Child_OnSize (HWND, UINT, short, short);            
  12. VOID NEAR PASCAL Child_OnSetFocus (HWND, HWND);
  13. VOID NEAR PASCAL Child_OnMDIActivate (HWND, BOOL, HWND, HWND);
  14. VOID NEAR PASCAL Child_OnCommand (HWND, UINT, HWND, UINT); 
  15. VOID NEAR PASCAL Child_OnDestroy (HWND);
  16. VOID NEAR PASCAL Child_OnClose(HWND);
  17. BOOL NEAR PASCAL Child_OnQueryEndSession (HWND);
  18. LONG NEAR PASCAL Child_OnDrawItem (HWND, const DRAWITEMSTRUCT FAR *);
  19. LONG NEAR PASCAL Child_OnMeasureItem (HWND, LPMEASUREITEMSTRUCT);
  20. VOID NEAR PASCAL Child_OnDropFiles (HWND, HDROP);
  21.  
  22. short NEAR PASCAL FigureOutWhereToInsert (HWND, LPPOINT);
  23. BOOL NEAR PASCAL InsertIconImage (short, HWND, short, LPSTR);
  24. BOOL NEAR PASCAL AddIconImage (short, HWND, LPSTR);
  25. VOID NEAR PASCAL HandleSelectionState (const DRAWITEMSTRUCT FAR *);
  26. VOID NEAR PASCAL HandleFocusState (const DRAWITEMSTRUCT FAR *);
  27.  
  28. #ifdef __cplusplus
  29. }
  30. #endif
  31.  
  32.  
  33. //////////////////////////////////////////////////////////////////////////
  34. //  ChildProc - Handles all of the messages for the Child animation
  35. //  window which shows all of the icons and their file names.
  36. //  The window procedure makes use of Message Crackers, a new
  37. //  idea introduced in the header file WINDOWSX.H.  Using this file
  38. //  is a good way to preserve your code for changes in upcoming versions
  39. //  of Windows, where types and parameters change.
  40. //////////////////////////////////////////////////////////////////////////
  41.  
  42. LRESULT _export CALLBACK ChildProc(WNDPROC_PARAMS)
  43. {
  44.     switch (uMsg) 
  45.     {
  46.         HANDLE_MSG (hWnd, WM_CREATE, Child_OnCreate);
  47.         HANDLE_MSG (hWnd, WM_SIZE, Child_OnSize);
  48.         HANDLE_MSG (hWnd, WM_SETFOCUS, Child_OnSetFocus);
  49.         HANDLE_MSG (hWnd, WM_MDIACTIVATE, Child_OnMDIActivate);
  50.         HANDLE_MSG (hWnd, WM_COMMAND, Child_OnCommand);
  51.         HANDLE_MSG (hWnd, WM_DRAWITEM, Child_OnDrawItem);
  52.         HANDLE_MSG (hWnd, WM_MEASUREITEM, Child_OnMeasureItem);
  53.         HANDLE_MSG (hWnd, WM_DESTROY, Child_OnDestroy);
  54.         HANDLE_MSG (hWnd, WM_CLOSE, Child_OnClose);
  55.         HANDLE_MSG (hWnd, WM_QUERYENDSESSION, Child_OnQueryEndSession);
  56.         HANDLE_MSG (hWnd, WM_DROPFILES, Child_OnDropFiles);
  57.     }
  58.  
  59.     return DefMDIChildProc(hWnd, uMsg, wParam, lParam);
  60. }
  61.             
  62.  
  63.  
  64. //////////////////////////////////////////////////////////////////////////
  65. //  Child_OnCreate() - Creates the listbox and initializes the data
  66. //  structure and window words for this window.
  67. //////////////////////////////////////////////////////////////////////////
  68.  
  69. BOOL NEAR PASCAL Child_OnCreate (HWND hwnd, LPCREATESTRUCT lpCS)
  70. {
  71.     short i,j;
  72.     HWND  hwndList = CreateWindow ("LISTBOX","",
  73.                                      WS_CHILD|WS_VISIBLE|
  74.                                      LBS_NOINTEGRALHEIGHT|
  75.                                      LBS_OWNERDRAWFIXED|LBS_HASSTRINGS|
  76.                                      LBS_NOTIFY|WS_VSCROLL|WS_BORDER,
  77.                                      0,0,0,0,hwnd,
  78.                                      IDD_LISTBOX, _hInst, NULL);
  79.     if (!IsWindow (hwndList)) 
  80.     {
  81.         return FALSE;
  82.     }
  83.  
  84.     SendMessage (hwndList, WM_SETFONT, GetStockFont(ANSI_VAR_FONT),0L);
  85.     DragAcceptFiles (hwnd, TRUE);
  86.  
  87.     i = (short)((LPMDICREATESTRUCT)lpCS->lpCreateParams)->lParam;
  88.     
  89.     SET_HWNDLIST (hwnd, hwndList);   // next three are window words.   
  90.     SET_WINDOWNUM (hwnd, i);
  91.     SET_ISDIRTY (hwnd, FALSE);   
  92.     SET_EXELOADED (i, FALSE);        // rest are in data structure.
  93.     SET_AUTOANIMATE (i, FALSE);
  94.     SZFILENAME(i)[0] = '\0';
  95.     SZEXELINK(i)[0] = '\0';
  96.     SET_HWNDANIM(i, hwnd);  
  97.     SET_INDEX (i, 0);
  98.     SET_NUMICONS (i, 0);
  99.     SET_TIMEINT (i, 100);   
  100.     
  101.  
  102.     for (j=0; j<(short)MAXICONS ; j++)
  103.     {
  104.         HICONS(i)[j] = NULL;
  105.     }
  106.  
  107.     UPDATE_STATBAR;
  108.  
  109.     return TRUE;
  110. }
  111.  
  112.  
  113.  
  114. //////////////////////////////////////////////////////////////////////////
  115. //  Child_OnSize() - Moves listbox accordingly, and sets column width.
  116. //////////////////////////////////////////////////////////////////////////
  117.  
  118. VOID NEAR PASCAL Child_OnSize (HWND hwnd, UINT wSizeType, short cx, short cy)            
  119. {
  120.     
  121.     if (LB_ERR==(WORD)SendMessage(HWNDLIST(hwnd),LB_SETCOLUMNWIDTH,cx-2,0L))
  122.     {
  123.         MESSAGE (IDS_ListBoxSize);
  124.     }
  125.  
  126.     MoveWindow(HWNDLIST(hwnd), 0, 0, cx, cy, TRUE);
  127.  
  128.     DefMDIChildProc(hwnd, WM_SIZE, (WPARAM)wSizeType, MAKELPARAM(cx,cy));
  129. }
  130.  
  131.  
  132.  
  133. //////////////////////////////////////////////////////////////////////////
  134. //  Child_OnDropFiles() - Handles the Drag-n-Drop protocol that File
  135. //  Manager in Windows 3.1 makes available to us.
  136. //////////////////////////////////////////////////////////////////////////
  137.  
  138. VOID NEAR PASCAL Child_OnDropFiles (HWND hwnd, HDROP hDrop)
  139. {
  140.     short  sChild   = WINDOWNUM (hwnd);
  141.     HWND   hwndList = HWNDLIST (hwnd);
  142.     short  sNumDrop = (short)DragQueryFile (hDrop,(WORD)-1,NULL,0);
  143.  
  144.     if (ISANIMATING(sChild))
  145.     {
  146.         MESSAGE (IDS_NoDropOnWhileAnimate);
  147.         return;
  148.     }
  149.  
  150.     if (sNumDrop > 0)
  151.     {
  152.         short i;
  153.         short sInsert;
  154.         POINT pt;
  155.         char   szDropFile [MAX_FILE_SIZE];    
  156.  
  157.         // get the point of up-click.  If up-click over an existing
  158.         // listbox entry, insert the files there.  Else, append.
  159.  
  160.         DragQueryPoint (hDrop, (LPPOINT)&pt);
  161.  
  162.         sInsert = FigureOutWhereToInsert (hwndList, (LPPOINT)&pt);
  163.         
  164.         for (i=0 ; i<(short)sNumDrop ; i++)
  165.         {
  166.             DragQueryFile (hDrop, i, (LPSTR)szDropFile, MAX_FILE_SIZE);
  167.  
  168.             if (sInsert < 0)
  169.             {
  170.                 AddIconImage (sChild, hwndList, (LPSTR)szDropFile);
  171.             }
  172.             else
  173.             {
  174.                 InsertIconImage (sChild, hwndList, sInsert, (LPSTR)szDropFile);
  175.             }    
  176.                         
  177.             SET_ISDIRTY (hwnd, TRUE);
  178.         }
  179.     }
  180. }
  181.  
  182.         
  183.  
  184. //////////////////////////////////////////////////////////////////////////
  185. //  Child_OnSetFocus() - Sets focus to the listbox.
  186. //////////////////////////////////////////////////////////////////////////
  187.  
  188. VOID NEAR PASCAL Child_OnSetFocus (HWND hwnd, HWND hwndPrev)
  189. {
  190.     SetFocus(HWNDLIST(hwnd));
  191. }
  192.  
  193.  
  194.  
  195. //////////////////////////////////////////////////////////////////////////
  196. //  Child_OnMDIActivate() - Sets up the menu accordingly, and updates
  197. //  the status bar, since the new active child may have a totally
  198. //  different state.
  199. //////////////////////////////////////////////////////////////////////////
  200.  
  201. VOID NEAR PASCAL Child_OnMDIActivate (HWND hwnd, BOOL bActive, 
  202.     HWND hwndActive, HWND hwndDeActive)
  203. {
  204.     SendMessage(_hwndClient, WM_MDISETMENU, (WPARAM)0,
  205.         bActive ? MAKELPARAM(_hmenuChild, _hmenuChildWindow)
  206.                 : MAKELPARAM(_hmenuMain, _hmenuMainWindow));
  207.  
  208.     DrawMenuBar(_hwndFrame);
  209.  
  210.     UPDATE_STATBAR;
  211.  
  212.     if (bActive)
  213.     {
  214.         SetFocus (hwnd);
  215.     }
  216.     
  217.     DefMDIChildProc(hwnd, WM_MDIACTIVATE, (WPARAM)bActive, 
  218.         MAKELPARAM(hwndActive,hwndDeActive));
  219. }
  220.  
  221.  
  222.  
  223. //////////////////////////////////////////////////////////////////////////
  224. //  Child_OnCommand() - Handles all of the command processing specific
  225. //  to an animation.
  226. //////////////////////////////////////////////////////////////////////////
  227.  
  228. VOID NEAR PASCAL Child_OnCommand (HWND hwnd, UINT uMsg, 
  229.         HWND hChild, UINT uExtra) 
  230. {
  231.     short sChild = WINDOWNUM(hwnd);
  232.  
  233.     switch (uMsg) 
  234.     {
  235.         case IDM_SETTINGS:
  236.         {
  237.             if (DialogBox (_hInst, SETTINGSDLG, hwnd, _lpfnSettings))
  238.             {
  239.                 UPDATE_STATBAR;
  240.                 SET_ISDIRTY (hwnd, TRUE);
  241.  
  242.                 if (AUTOANIMATE (sChild))
  243.                 {
  244.                     PostMessage (hwnd, WM_COMMAND, IDM_GO, 0L);
  245.                 }
  246.             }
  247.             break;
  248.         }
  249.  
  250.         case IDM_GO:
  251.         {            
  252.             if (!NUMICONS(sChild))
  253.             {
  254.                 MESSAGE (IDS_NoIcons);
  255.                 break;
  256.             }
  257.  
  258.             if (!TIMEINT(sChild) || !SZEXELINK(sChild)[0])
  259.             {
  260.                 SendMessage (_hwndFrame, WM_COMMAND, IDM_SETTINGS, 0L);
  261.             }
  262.  
  263.             if (SZEXELINK(sChild) && TIMEINT(sChild))
  264.             {
  265.                 // Free old icon handles before creating new ones.
  266.                 // 
  267.                 DeletePreviousHandles (hwnd);
  268.                 SetupIconHandles (hwnd);
  269.                 SET_INDEX (sChild, 0);
  270.                 SET_ISANIMATING (sChild, TRUE);
  271.             }
  272.  
  273.             break;
  274.         }
  275.  
  276.         case IDM_STOP:
  277.         {
  278.             SET_ISANIMATING (sChild, FALSE);
  279.  
  280.             if (IsWindow (HWNDTARGET(sChild)))
  281.             {
  282.                 SetClassWord (HWNDTARGET(sChild), GCW_HICON, 
  283.                     HPREVICON(sChild));
  284.  
  285.                 InvalidateAll (HWNDTARGET(sChild),HPREVICON(sChild));
  286.             }
  287.  
  288.             break ;
  289.         }       
  290.          
  291.         case IDM_SAVE:
  292.         case IDM_SAVEAS:
  293.         {
  294.             SaveIconsToFile (hwnd, uMsg);
  295.             SET_ISDIRTY (hwnd, FALSE);
  296.             break;
  297.         }
  298.  
  299.         case IDM_ADDICON:
  300.         case IDM_INSERTICON:
  301.         {
  302.             char szAddFile [MAX_FILE_SIZE];
  303.  
  304.             getcwd (szAddFile, MAX_FILE_SIZE);
  305.  
  306.             if (ShowCommonDialog(hwnd,_lpszIconFilter,
  307.                 (LPSTR)szAddFile, (LPSTR)"Add or Insert Icon...\0",
  308.                 (LPSTR)"*.ICO", FALSE))
  309.             {
  310.                 HWND hwndList = HWNDLIST (hwnd);
  311.                 
  312.                 if (!IsWindow (hwndList)) 
  313.                 {
  314.                     break;
  315.                 }
  316.  
  317.                 if (uMsg == IDM_INSERTICON)
  318.                 {
  319.                     short sSel = (short)ListBox_GetCurSel (hwndList);
  320.  
  321.                     if (sSel == LB_ERR)
  322.                     {
  323.                         MESSAGE (IDS_PleaseSelect);
  324.                     }
  325.                     else
  326.                     {
  327.                         InsertIconImage (sChild, hwndList, sSel, 
  328.                                                 (LPSTR)szAddFile);
  329.                     }
  330.                 }
  331.                 else
  332.                 {
  333.                     AddIconImage (sChild, hwndList, (LPSTR)szAddFile);
  334.                 }
  335.                 
  336.                 SET_ISDIRTY (hwnd, TRUE);
  337.             }
  338.  
  339.             break;
  340.         }
  341.  
  342.         case IDM_DELETEICON:
  343.         {
  344.             DeleteCurSel (hwnd);           
  345.             SET_ISDIRTY (hwnd, TRUE);
  346.             break;
  347.         }
  348.         default:
  349.             return;
  350.     }
  351.  
  352.     UPDATE_STATBAR;
  353. }
  354.  
  355.  
  356.  
  357. //////////////////////////////////////////////////////////////////////////
  358. //  Child_OnDestroy() - frees all memory handles used for icons, and
  359. //  resets the animStruct for this window to all zeros.
  360. //////////////////////////////////////////////////////////////////////////
  361.  
  362. VOID NEAR PASCAL Child_OnDestroy (HWND hWnd)
  363. {   
  364.     int i;
  365.     short sChild = WINDOWNUM(hWnd);
  366.  
  367.     if (ISANIMATING(sChild)) 
  368.     {
  369.         SET_ISANIMATING (sChild, FALSE);
  370.         
  371.         if (IsWindow (HWNDTARGET(sChild)))
  372.         {
  373.             SetClassWord (HWNDTARGET(sChild), GCW_HICON, HPREVICON(sChild));
  374.             InvalidateAll (HWNDTARGET(sChild),HPREVICON(sChild));
  375.         }
  376.     }
  377.  
  378.     DestroyWindow(HWNDLIST(hWnd));
  379.  
  380.     for (i=0; i<(short)NUMICONS(sChild) ; i++)
  381.     {
  382.         GlobalFree (HICONS(sChild)[i]);
  383.         HICONS(sChild)[i] = NULL;  // reset the structure to all nulls
  384.     }
  385.  
  386.     _fmemset ((LPANIMSTRUCT)&_animStruct[sChild], 0x00, sizeof(ANIMSTRUCT));            
  387.  
  388.     _lPageFlags &= 0xFFFFFFFFL ^ (1 << sChild);
  389.  
  390.     DefMDIChildProc(hWnd, WM_DESTROY, (WPARAM)0, (LPARAM)0L);
  391. }
  392.  
  393.  
  394.  
  395. //////////////////////////////////////////////////////////////////////////
  396. //  Child_OnClose() -  Checks with QueryEndSession to see if it is ok
  397. //  with the user to close, then closes, by calling Destroy.
  398. //////////////////////////////////////////////////////////////////////////
  399.  
  400. VOID NEAR PASCAL
  401. Child_OnClose (HWND hwnd)
  402. {
  403.     if (SendMessage(hwnd, WM_QUERYENDSESSION, 0, 0L))
  404.     {
  405.         MDI_Destroy (_hwndClient, hwnd);  
  406.     }
  407. }
  408.  
  409.  
  410.  
  411. //////////////////////////////////////////////////////////////////////////
  412. //  Asks whether or not to save changes, if changes need to be saved.
  413. //  If everything is cool, or the user presses NO, we say its OK to 
  414. //  close, as FrameProc()'s BroadcastProc() is the one calling this.
  415. //  This child also calls it when a WM_CLOSE message comes its way.
  416. //////////////////////////////////////////////////////////////////////////
  417.  
  418. BOOL NEAR PASCAL Child_OnQueryEndSession (HWND hWnd)
  419. {
  420.     char szBigString [192];
  421.     char szWindowText [MAX_FILE_SIZE];
  422.     char szFmtString [36];
  423.  
  424.     if (ISDIRTY(hWnd))
  425.     {
  426.         short sChild = WINDOWNUM(hWnd);
  427.         UINT uReply;
  428.  
  429.         GetWindowText (hWnd, (LPSTR)szWindowText, MAX_FILE_SIZE);
  430.  
  431.         LoadStr(IDS_QueryEnd, szFmtString);    
  432.         wsprintf ((LPSTR)szBigString,
  433.                   (LPSTR)szFmtString,
  434.                   (LPSTR)szWindowText);
  435.  
  436.         uReply = MessageBox (hWnd, szBigString, _szAppName, MB_YESNOCANCEL);
  437.  
  438.         if (uReply == IDYES)
  439.         {
  440.             SendMessage (hWnd, WM_COMMAND, (WPARAM)(SZFILENAME(sChild)[0] ? 
  441.                 IDM_SAVE : IDM_SAVEAS), (LPARAM)0L);
  442.             return TRUE;
  443.         }    
  444.         else if (uReply == IDCANCEL)
  445.         {
  446.             return FALSE;
  447.         }
  448.     }
  449.  
  450.     return TRUE;
  451. }
  452.  
  453.  
  454.  
  455. //////////////////////////////////////////////////////////////////////////
  456. //  Child_OnDrawItem() - Does the meat of the drawing for each item
  457. //  in the listbox, and calls the HandleFocusState() and HandleSelection()
  458. //  functions as necessary.
  459. //////////////////////////////////////////////////////////////////////////
  460.  
  461. LONG NEAR PASCAL Child_OnDrawItem (HWND hwnd, const DRAWITEMSTRUCT FAR * lp)
  462. {
  463.     short sChild = WINDOWNUM(hwnd);
  464.  
  465.     if ((lp->CtlType == ODT_LISTBOX) && (lp->CtlID == IDD_LISTBOX))
  466.     {
  467.         if (NUMICONS(sChild) == 0) 
  468.         {
  469.             return 0L;
  470.         }
  471.  
  472.         if (lp->itemAction & ODA_DRAWENTIRE)
  473.         {
  474.             DrawIcon (lp->hDC,                                        
  475.                      (lp->rcItem.right - lp->rcItem.left - ICON_DX)/2, 
  476.                       lp->rcItem.top+(PADDING/2),   
  477.                       HICONS(sChild)[lp->itemID]);                     
  478.  
  479.             HandleSelectionState(lp);
  480.         }
  481.  
  482.         // If a list box item was just selected or unselected,
  483.         // call function (which could check if ODS_SELECTED bit is set)
  484.         // and draw item in selected or unselected state.
  485.  
  486.         if (lp->itemAction & ODA_SELECT)
  487.         {
  488.             HandleSelectionState(lp);
  489.         }
  490.  
  491.         return 1L;
  492.     }
  493.     return 0L;
  494. }
  495.  
  496.  
  497.  
  498. //////////////////////////////////////////////////////////////////////////
  499. //  Child_OnMeasureItem() - tells Windows how to size the listbox.
  500. //////////////////////////////////////////////////////////////////////////
  501.  
  502. LONG NEAR PASCAL Child_OnMeasureItem (HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
  503. {   
  504.     lpmis->itemHeight = GetANSITextHeight()+ICON_DY+PADDING;
  505.     return 0L;
  506. }
  507.  
  508.  
  509.  
  510.  
  511. //////////////////////////////////////////////////////////////////////////
  512. //  HandleSelectionState() - Handles the drawing of the listbox with
  513. //  current selection, and draws an un-selected one.  The item being
  514. //  selected and the one being un-selected are dealt with here.
  515. //////////////////////////////////////////////////////////////////////////
  516.  
  517. VOID NEAR PASCAL HandleSelectionState(const DRAWITEMSTRUCT FAR * lp)
  518. {   
  519.     BOOL fOn = lp->itemState & ODS_SELECTED;
  520.     short sIndent;
  521.     short sDownSpace;
  522.     UINT oldBkMode;
  523.     COLORREF oldTextColor;
  524.     DWORD dwExtent;
  525.     RECT rc;
  526.     HBRUSH hBrush;
  527.  
  528.     CopyRect (&rc, &lp->rcItem);
  529.  
  530.     ListBox_GetText (lp->hwndItem, lp->itemID, (LPSTR)szAllPurpose);
  531.     dwExtent = GetTextExtent (lp->hDC, (LPSTR)szAllPurpose, 
  532.         lstrlen((LPSTR)szAllPurpose));
  533.  
  534.     sIndent = ((short)(rc.right-rc.left-LOWORD(dwExtent)) / 2);
  535.     sDownSpace = (short)(rc.bottom-rc.top-HIWORD(dwExtent));
  536.  
  537.     /* Setup formatting rectangle */
  538.     rc.left  += sIndent;
  539.     rc.right -= sIndent;
  540.     rc.top   += sDownSpace;
  541.  
  542.     /* Use the title bar colors for highlighting, so we
  543.        set the text color and bk color to those colors,
  544.        draw the text, then reset the colors back to original
  545.        values */
  546.  
  547.     oldBkMode = SetBkMode (lp->hDC, TRANSPARENT);
  548.         
  549.     oldTextColor = SetTextColor (lp->hDC, 
  550.         Color(fOn ? COLOR_CAPTIONTEXT : COLOR_WINDOWTEXT));
  551.  
  552.     hBrush = CreateSolidBrush(Color (fOn ? COLOR_ACTIVECAPTION :
  553.                                            COLOR_WINDOW));
  554.     FillRect (lp->hDC, &rc, hBrush);
  555.     DeleteBrush (hBrush);
  556.  
  557.     ExtTextOut (lp->hDC, rc.left, rc.top,
  558.         ETO_CLIPPED,
  559.         (LPRECT)&rc,
  560.         (LPSTR)szAllPurpose,
  561.         lstrlen ((LPSTR)szAllPurpose),
  562.         NULL);
  563.  
  564.     SetBkMode (lp->hDC, oldBkMode);
  565.     SetTextColor (lp->hDC, oldTextColor);
  566.  
  567. }
  568.     
  569.  
  570.  
  571.  
  572.  
  573.  
  574. //////////////////////////////////////////////////////////////////////////
  575. // FigureOutWhereToInsert() - Given the listbox and a point somewhere
  576. // in the listbox when the user up-clicked the LBUTTON, we find out
  577. // where, then return an index if they up-clicked over an item.  If not,
  578. // we return telling them to append to end of list.
  579. //////////////////////////////////////////////////////////////////////////
  580.  
  581. short NEAR PASCAL FigureOutWhereToInsert (HWND hwndList, LPPOINT lppt)
  582. {
  583.     short  sCount = (short)ListBox_GetCount (hwndList);
  584.     short  i;
  585.     RECT   rc;
  586.  
  587.     for (i=0 ; i<sCount ; i++)
  588.     {
  589.         ListBox_GetItemRect (hwndList, i, (LPRECT)&rc);
  590.  
  591.         if (!PtInRect ((LPRECT)&rc, *lppt)) continue;
  592.         return i;
  593.     }
  594.  
  595.     return (short)(-1);
  596. }
  597.  
  598.  
  599.  
  600. //////////////////////////////////////////////////////////////////////////
  601. // InsertIconImage() - inserts an icon into a specific position in the
  602. // list.
  603. //////////////////////////////////////////////////////////////////////////
  604.  
  605. BOOL NEAR PASCAL InsertIconImage (short sChild, HWND hwndList,
  606.     short sInsert, LPSTR lpszFile)
  607. {
  608.     short sNumIcons = NUMICONS (sChild);
  609.     HICON hNewIcon;
  610.     short i;
  611.  
  612.     if (sNumIcons >= MAXICONS)
  613.     {
  614.         MESSAGE (IDS_TooManyIcons);
  615.         return FALSE;
  616.     }
  617.  
  618.     hNewIcon = ExtractIcon (_hInst, lpszFile, 0);
  619.  
  620.     if (hNewIcon == NULL) return FALSE;
  621.  
  622.     if (sNumIcons == 0)
  623.     {
  624.         HICONS(sChild)[sNumIcons] = hNewIcon;
  625.     }
  626.     else
  627.     {
  628.         for (i=sNumIcons ; i>=0 ; i--)
  629.         {   
  630.             HICONS(sChild)[i] = HICONS(sChild)[i-1];
  631.             if ( (i-1) == sInsert)
  632.             {
  633.                 HICONS(sChild)[i-1] = hNewIcon;
  634.                 break;
  635.             }
  636.         }
  637.     }
  638.  
  639.     sNumIcons++;
  640.  
  641.     SET_NUMICONS (sChild, sNumIcons);
  642.  
  643.     if (LB_ERR == ListBox_InsertString(hwndList,sInsert,lpszFile))
  644.     {
  645.         MESSAGE(IDS_AddFileError);
  646.         return FALSE;
  647.     }
  648.     
  649.     ListBox_SetCurSel (hwndList, sInsert);
  650.  
  651.     return TRUE;
  652. }   
  653.  
  654.  
  655.  
  656. //////////////////////////////////////////////////////////////////////////
  657. //  AddIconImage() - Adds an icon to the end of the list.
  658. //////////////////////////////////////////////////////////////////////////
  659.  
  660. BOOL NEAR PASCAL AddIconImage (short sChild, HWND hwndList, 
  661.     LPSTR lpszFile)
  662. {
  663.     HICON hNewIcon;
  664.     short sNumIcons = NUMICONS(sChild);
  665.  
  666.     if (sNumIcons >= MAXICONS)
  667.     {
  668.         MESSAGE (IDS_TooManyIcons);
  669.         return FALSE;
  670.     }
  671.  
  672.     hNewIcon = ExtractIcon (_hInst, lpszFile, 0);
  673.  
  674.     if (hNewIcon == NULL) return FALSE;
  675.  
  676.     HICONS(sChild)[sNumIcons] = hNewIcon;
  677.     sNumIcons++;
  678.     SET_NUMICONS (sChild, sNumIcons);
  679.     
  680.     if (LB_ERR == ListBox_AddString(hwndList,lpszFile))
  681.     {
  682.         MESSAGE(IDS_AddFileError);
  683.         return FALSE;
  684.     }
  685.     
  686.     ListBox_SetCurSel (hwndList, ListBox_GetCount(hwndList)-1);
  687.  
  688.     return TRUE;
  689. }
  690.  
  691.